/** 
 * Project Name: farm-core 
 * File Name: DefaultPlaintextDecoder.java 
 * Package Name: com.bugull.farm.core.codec 
 * Date: 2017年2月22日下午5:06:46 
 * Copyright (c) 2017, hadlinks All Rights Reserved. 
 * 
 */
package com.bugull.farm.core.codec;

import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.*;
import com.bugull.farm.core.frame.exception.BuguException;
import com.bugull.farm.core.frame.structure.Frame;
import com.bugull.farm.core.utils.BufUtil;
import com.bugull.farm.core.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

/** 
 * ClassName: DefaultPlaintextDecoder 
 * Function: 默认的frame解码器，将ByteBuf数据转化成自定义的frame类型.  
 * date: 2017年2月22日 下午5:06:46  
 * 
 * @author songwei (songw@hadlinks.com)
 * @version 
 * @since JDK 1.8 
 */
public class DefaultFrameDecoder extends ByteToMessageDecoder{
	
	private final Logger logger = LogManager.getLogger(DefaultFrameDecoder.class);

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in,
			List<Object> out) throws Exception {
			//记录原始日志
			logger.debug(ByteUtil.toHexString(BufUtil.getArray(in)));
			//转化成文本内容对象交由pipeline下游的handler处理
			Frame frame = new Frame(in);
			String log = "";
			Map<String, Object> temp = frame.getRequestMap();
			for(String key : temp.keySet()){
				log += ("["+key+"]:"+"["+temp.get(key)+"] **");
			}
			//记录文本日志
			logger.debug(log);
			out.add(frame);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		cause.printStackTrace();
		logger.error("Channel closed beacuse an exception caught : " + cause);
		Channel ch = ctx.channel();
		if (cause instanceof BuguException) {
			BuguException e = (BuguException) cause;
			if (ch.isActive()) {
				ctx.writeAndFlush(e.getErrorResponse()).addListener(ChannelFutureListener.CLOSE);			
			}
		} else {
			if (ch.isActive()) {
	            ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
	        }
		}
	}
}
